"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 文件目录
Case Name   : 主节点删除表文件
Create At   : 2020/07/22
Owner       : @li-xin12345
Description :
    1. 执行DDL新建表
    2. 手动删除主机的表文件
    3. 重启数据库
    4. 主机进行表查询
    5. 备机进行表查询
Expect      :
    1.成功
    2.删除文件成功
    3.重启成功
    4.失败
    5.成功
History     :
    Modified by: @wan005 at 2021.9/27 将正常stop改为kill -9
    Modified by: @wan005 at 2022/3/16 研发代码变更，重启后表文件无法恢复
    Modified by: @zou_jialiang050 at 2022/5/26 删除表文件之前执行checkpoint
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

logger = Logger()

class IndexFileDamaged(unittest.TestCase):
    commonshpri = CommonSH('PrimaryDbUser')
    commonshsta = CommonSH('Standby1DbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        f"-----{os.path.basename(__file__)[:-3]} start-----"
        self.dbPrimaryDbUser = Node(node='PrimaryDbUser')
        self.dbPrimaryRoot = Node(node='PrimaryRoot')
        self.dbStandby1DbUser = Node(node='Standby1DbUser')
        self.Constant = Constant()
        self.common = Common('PrimaryRoot')
        self.tblname = 'reliability_dbsys_case189'
        self.tblpath = ''
        self.valuenum = 100000
        self.tblname_bak = 'tbl_bak'
        self.com_pri = Common('PrimaryRoot')
        self.db_primary_root_node = Node(node='PrimaryRoot')

    def test_Index_file_damaged(self):
        self.log.info('-------------------创建数据表，并插入数据-----------------------------------')
        sql = f'drop table if exists {self.tblname}; create table {self.tblname}(id int); insert into {self.tblname} values(generate_series(1,{self.valuenum}));checkpoint;'
        result = self.commonshpri.executDbSql(sql)
        self.log.info(result)

        # 创建备份表
        sql = f'drop table if exists {self.tblname_bak}; create table {self.tblname_bak}(id int); insert into {self.tblname_bak} select * from {self.tblname};checkpoint;'
        result = self.commonshpri.executDbSql(sql)
        self.log.info(result)

        self.log.info('----------------------------查询表文件路径----------------------')
        o_id = self.commonshpri.executDbSql(f'select oid from pg_class where relname=\'{self.tblname}\';')
        self.log.info(o_id)
        oid = o_id.splitlines()[-2]
        self.log.info(oid)
        result = self.commonshpri.executDbSql(f'Select pg_relation_filepath({oid}::regclass);')
        self.log.info(result)
        indexpath_tmp = result.splitlines()[-2].strip()
        self.tblpath = os.path.join(macro.DB_INSTANCE_PATH, indexpath_tmp)
        self.log.info(f'table path is: {self.tblpath}')

        self.log.info('------------------------waiting dirtypage update-------------------')
        result = self.commonshpri.check_whether_remain_dirty_page()
        self.assertTrue(result)

        result = self.commonshpri.check_data_consistency()
        self.assertTrue(result)

        self.log.info('----------------------------删除主节点表文件-----------------------------')
        excute_cmd = f'rm -rf  {self.tblpath}* ;ls -al {self.tblpath}* '
        self.log.info(excute_cmd)
        msg = self.dbPrimaryDbUser.sh(excute_cmd).result()
        self.log.info(msg)

        self.log.info('-------------------重启数据库-------------------------------')
        time.sleep(60)
        self.log.info('查询数据库状态')
        status = self.commonshpri.getDbClusterStatus("status")
        self.log.info(status)
        result = self.com_pri.kill_pid(self.db_primary_root_node, '9')
        self.log.info(result)
        result = self.commonshpri.startDbCluster()
        self.assertTrue(result)
        excute_cmd = f'ls -al {self.tblpath}*'
        self.log.info(excute_cmd)
        msg = self.dbPrimaryDbUser.sh(excute_cmd).result()
        self.log.info(msg)
        self.assertIn(self.Constant.NO_FILE_MSG, msg)

        self.log.info('-------------------查询主备数据库对应表数据-------------------')

        time.sleep(2)
        excute_cmd = f'ls -al {self.tblpath}*'
        self.log.info(excute_cmd)
        msg = self.dbPrimaryDbUser.sh(excute_cmd).result()
        self.log.info(msg)
        sql = f'select count(*) from {self.tblname};'
        result = self.commonshpri.executDbSql(sql)
        self.log.info(result)
        self.assertIn(self.Constant.OPEN_FAIL, result)
        result = self.commonshsta.executDbSql(sql)
        self.log.info(result)
        self.assertIn(str(self.valuenum), result)
        sql = f'select * from {self.tblname_bak} except select * from {self.tblname};'
        result = self.commonshpri.executDbSql(sql)
        self.log.info(result)
        self.assertIn(self.Constant.OPEN_FAIL, result)

    def tearDown(self):
        logger.info('----------------------------this is tearDown-----------------------------')
        logger.info('----------------------------drop table-----------------------------')
        result = self.commonshpri.executDbSql(
            f'drop table if exists {self.tblname};drop table if exists {self.tblname_bak};')
        self.log.info(result)
        logger.info(f"-----{os.path.basename(__file__)[:-3]} end-----")
